package com.licq.ldoc.domain;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.sql.Time;
import java.sql.Timestamp;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.Predicate;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class AttributeTypeConverter {
	private static transient Log logger = LogFactory.getLog(AttributeTypeConverter.class);
	
    private static Map<Class<?>, AttributeType> classMap = new HashMap<Class<?>, AttributeType>();

    static {
        classMap.put(Integer.class, AttributeType.INT);
        classMap.put(Short.class, AttributeType.SHORT);
        classMap.put(Long.class, AttributeType.LONG);
        classMap.put(Character.class, AttributeType.CHAR);
        classMap.put(Float.class, AttributeType.FLOAT);
        classMap.put(Double.class, AttributeType.DOUBLE);
        classMap.put(Byte.class, AttributeType.BYTE);
        classMap.put(Boolean.class, AttributeType.BOOLEAN);
        classMap.put(String.class, AttributeType.STRING);
        classMap.put(BigDecimal.class, AttributeType.BIGDECIMAL);
        classMap.put(BigInteger.class, AttributeType.BIGINTEGER);
        classMap.put(Date.class, AttributeType.DATE);
        classMap.put(Calendar.class, AttributeType.CALENDAR);
        classMap.put(java.sql.Date.class, AttributeType.SQLDATE);
        classMap.put(Time.class, AttributeType.TIME);
        classMap.put(Timestamp.class, AttributeType.TIMESTAMP);
        classMap.put(Class.class, AttributeType.CLASS);
        classMap.put(Enum.class, AttributeType.ENUM);
        classMap.put(Object.class, AttributeType.OBJECT);
        classMap.put(Integer.TYPE, AttributeType.INT);
        classMap.put(Short.TYPE, AttributeType.SHORT);
        classMap.put(Long.TYPE, AttributeType.LONG);
        classMap.put(Character.TYPE, AttributeType.CHAR);
        classMap.put(Float.TYPE, AttributeType.FLOAT);
        classMap.put(Double.TYPE, AttributeType.DOUBLE);
        classMap.put(Byte.TYPE, AttributeType.BYTE);
        classMap.put(Boolean.TYPE, AttributeType.BOOLEAN);
    }

    public AttributeType convert(Class<?> clazz) {
        return classMap.get(clazz);
    }
    
    @SuppressWarnings("unchecked")
	public Class<?> convert(final AttributeType type) {
    	Object clazz = ((Entry<Class<?>, AttributeType>) CollectionUtils.find(classMap.entrySet(), new Predicate() {
    		@SuppressWarnings("unchecked")
			@Override
    		public boolean evaluate(Object object) {
    			Entry<Class<?>, AttributeType> entry = (Entry<Class<?>, AttributeType>) object;
    			return entry.getValue() == type && !entry.getKey().isPrimitive();
    		}
    	})).getKey();
    	if (clazz == null) {
    		if (logger.isErrorEnabled()) {
    			logger.error(String.format("cannot find class by attribute type[%s].", 
    					type.getLabel()
    				)
    			);
    		}
    	}
		return (Class<?>) clazz;
    }
    
}
